package com.pai4j.message.template;

import com.pai4j.message.core.template.AbstractTemplateEngine;
import com.pai4j.message.factory.TemplateEngineFactory;
import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import jakarta.annotation.PostConstruct;
import java.util.Map;

/**
 * FreeMarker模板引擎
 * 使用FreeMarker进行模板渲染
 *
 * @author PAI4J Team
 * @date 2025-11-01
 */
@Slf4j
@Component
public class FreeMarkerTemplateEngine extends AbstractTemplateEngine {

    private Configuration configuration;

    @PostConstruct
    public void init() {
        configuration = new Configuration(Configuration.VERSION_2_3_23);
        StringTemplateLoader loader = new StringTemplateLoader();
        configuration.setTemplateLoader(loader);
        configuration.setClassicCompatible(true);
        
        TemplateEngineFactory.register(this);
        log.info("FreeMarkerTemplateEngine已注册");
    }

    @Override
    public String getName() {
        return "freemarker";
    }

    @Override
    protected String doRender(String template, Map<String, Object> context) {
        if (template == null || template.isEmpty()) {
            return "";
        }

        try {
            // 为每个模板创建唯一名称
            String templateName = "template_" + template.hashCode();
            
            // 加载模板
            StringTemplateLoader loader = (StringTemplateLoader) configuration.getTemplateLoader();
            loader.putTemplate(templateName, template);
            
            // 获取并渲染模板
            Template tmpl = configuration.getTemplate(templateName);
            return FreeMarkerTemplateUtils.processTemplateIntoString(tmpl, context);
            
        } catch (Exception e) {
            log.error("FreeMarker模板渲染失败: template={}, error={}", template, e.getMessage());
            return template;
        }
    }

    @Override
    public int getPriority() {
        return 50; // 中等优先级
    }
}

